rm(list = ls(all = TRUE))
setwd("C:\\Users\\lenovo\\Desktop\\R\\神经网络_R语言实现")
#2.1 机器学习

#2.1.1 有监督学习

#2.1.2 无监督学习
#聚类（K均值，分层）
#协同技术
#降维
#自组织映射（self organizing map，SOM）/Kohonen网络

#2.1.3 强化学习
#存在可帮助机器学习适应环境的持续反馈
#每一步都有一个绩效评估来改进模型
#对于神经网络，有一种称为Q学习的特殊类型，
#结合神经元来实现反向传播反馈机制中的强化学习
#具体细节不表

#2.2 训练和测试模型
#2.3 数据循环
#工作流程

#2.4 评估指标

#2.5 学习神经网络
#前馈神经网络的学习过程发生在反向传播阶段
#模型通过减少每次迭代中的误差来微调权重
#梯度下降被用在反向传播阶段

#2.6 反向传播
#依靠微积分更新每个层的权重与偏差
#类似于 从错误中学习
#在每次迭代中自行改正错误（误差），直到到达一个收敛点（convergence）
#反向传播的目的是修正每个层的权重，并最小化输出层的整体误差

#2.7 神经网络学习算法的优化
#学习算法是指机器学习算法选择何种模型作为最优模型，
#目的是最小化损失函数

#下面是一些除梯度下降意外的优化技术

#1、粒子群优化（Particle Swarm Optimization，PSO）方法的灵感来源于对鸟群在寻找食物或生存过程中
#的运动的社会行为与集体行为的观察
#当知道粒子的位置与速度时，
#PSO方法的目的是在一个由关于位置与速度的数学方程控制的空间寻找一个解集
#它从生物有机体的行为中得到了集体智慧的启发

#2、模拟退火（simulated annealing）
#一种获得一个成本函数近似全局最优解的概率演算法
#通过模拟的方法在一个巨大的空间中搜索一个解

#3、进化（evolutionary）
#源于生物学的进化过程，进化可以是生殖、突变、选择和重组
#适应度函数被用于决定模型的性能，基于这个函数，选择最终的模型

#4、最大期望算法（Exprectation Maximization，EM）
#一种统计学习方法，使用一个迭代的方法寻找最大似然估计或最大后验估计，从而最小化误差

#2.8 神经网络中的有监督学习
#2.8.1 波士顿数据集
#2.8.2 对波士顿数据集进行神经网络回归

#加载包
library(neuralnet)
library(MASS)

#生成随机数
set.seed(1)

#加载数据
data = Boston

#对数据进行标准化
#避免一些不必要的结果或非常困难的训练过程
#可以进行Z标准化、最小-最大标准化（特征缩放）
#特征缩放是为了将所有的标准化后的数据处于0-1之间
#apply：1代表行、2代表列
max_data <- apply(data, 2, max)
min_data <- apply(data, 2, min)
data_scaled <- scale(data, center = min_data, scale =  max_data - min_data)

#把数据分成7：3，分别用于训练与测试
index = sample(1:nrow(data), round(0.70*nrow(data)))
train_data <- as.data.frame(data_scaled[index,])
test_data <- as.data.frame(data_scaled[-index,])

#构建神经网络并绘制
n = names(data)
f = as.formula(paste("medv ~", paste(n[!n %in% "medv"], collapse = " + ")))
f
net_data <- neuralnet(f, data = train_data, hidden = 10, linear.output = T)
plot(net_data)

#预测
predict_net_test = compute(net_data, test_data[, 1:13])

#准备用均方误差（MSE）度量预测值与实际值之间的差距
predict_net_test_start <- predict_net_test$net.result*(max(data$medv)- 
                                                         min(data$medv))+min(data$medv)
test_start <- as.data.frame((test_data$medv)*(max(data$medv)-
                                                min(data$medv))+min(data$medv))
MSE.net_data <- sum((predict_net_test_start - test_start)^2)/nrow(test_start)

#建立线性回归模型、拟合并计算MSE
Regression_Model <- lm(medv~., data = data)
summary(Regression_Model)
test <- data[-index,]
predict_lm <- predict(Regression_Model, test)
MSE.lm <- sum((predict_lm - test$medv)^2)/nrow(test)

#比较神经网络的MSE与线性回归模型的MSE
MSE.net_data
MSE.lm

#虽然神经网络的MSE更大一些，但是通过调整随机数，可以筛选出较小的

#2.9 神经网络中的无监督学习
#有 竞争学习 与 Kohonen SOM 两种
#Kohonen SOM由Teuvo Kohonen教授发明，在低维度呈现多维数据
#2.9.1 竞争学习
#神经网络中的节点相互竞争，以获得对数据子集做出响应的权力。
#隐含层称为竞争层
#每个竞争神经元拥有自己的权重
#输出神经元被认为是对输入模式的竞争
#只有获胜的神经元被更新

#2.9.2 Kohonen SOM
#竞争学习与临近神经元的概念相结合得到了Kohonen SOM
#输出层每个神经元有两个邻居
#应用于聚类、数据抽象、降维等多个领域

#install.packages("kohonen")
#加载包
library(kohonen)

#加载数据
data(wines)
str(wines)
head(wines)
View(wines)

#设定随机数种子并建模
set.seed(1)
som.wines = som(scale(wines), grid = somgrid(5,5,"hexagonal"))
som.wines
dim(getCodes(som.wines))

#绘图
plot(som.wines, main = "Wine data Kohonen SOM")
par(mfrow = c(1,1))
#绘制函数中到最近的神经元的平均距离和迭代次数之间的关系
plot(som.wines, type = "changes", main = "Wine data1: SOM")

#设计训练集与测试集
training = sample(nrow(wines),150)
Xtraining = scale(wines[training,])
Xtest = scale(wines[-training,],
              center = attr(Xtraining, "scaled:center"),
              scale = attr(Xtraining, "scaled:scale"))
trainingdata = list(measurements = Xtraining,
                    vintages = vintages[training])
testdata = list(measurements = Xtest, vintages = vintages[-training])
mygrid = somgrid(5,5,"hexagonal")
#受监督的SOM模型
som.wines = supersom(trainingdata, grid = mygrid)

som.prediction = predict(som.wines, newdata = testdata)
#调用函数table，使用交叉分类因子来建立每个因子水平次数的列联表
table(vintages[-training], som.prediction$predictions[["vintages"]])



